package com.orcamento.entity.report;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.joda.time.DateTime;

import com.orcamento.entity.Gain;
import com.orcamento.entity.Spent;
import com.orcamento.entity.enums.Month;
import com.orcamento.entity.report.subreport.MonthBalance;
import com.orcamento.entity.report.subreport.MonthGain;
import com.orcamento.entity.report.subreport.MonthSpent;
import com.orcamento.util.AppConfig;

public class GeneralBalanceReport extends Report {

	private List<MonthGain> monthGainReport = new ArrayList<MonthGain>();
	private List<MonthSpent> monthSpentReport = new ArrayList<MonthSpent>();
	
	private List<MonthBalance> moreProfitMonthBalanceReport = new ArrayList<MonthBalance>();
	private List<MonthBalance> lessProfitMonthBalanceReport = new ArrayList<MonthBalance>();
	
	public GeneralBalanceReport(Month month, Integer year) {
		super(month, year);
	}
	
	@Override
	public void generate() {
		excludeCreditCardSpents();
		generateTotalGainBalanceByMonth();
		generateTotalSpentBalanceByMonth();
		generateMoreProfitMonthBalanceReport();
	}
	
	public void generateTotalGainBalanceByMonth() {
		DateTime currentMonth = AppConfig.getStartDate();
		while( currentMonth.isBefore( new DateTime() ) ) {
			List<Gain> gains = getGainOf(currentMonth.getMonthOfYear(), currentMonth.getYear());
			monthGainReport.add( new MonthGain(currentMonth.getMonthOfYear(), currentMonth.getYear(), gains) );
			
			currentMonth = currentMonth.plusMonths(1);
		}
		
		Collections.sort(monthGainReport, Collections.reverseOrder());
	}
	
	public void generateMoreProfitMonthBalanceReport() {
		if( lessProfitMonthBalanceReport.isEmpty() ) {
			generateLessProfitMonthBalanceReport();
		}
		moreProfitMonthBalanceReport = new ArrayList<MonthBalance>(lessProfitMonthBalanceReport);
		Collections.sort( moreProfitMonthBalanceReport, Collections.reverseOrder() );
	}
	
	public void generateLessProfitMonthBalanceReport() {
		DateTime currentMonth = AppConfig.getStartDate();
		while( currentMonth.isBefore( new DateTime() ) ) {
			List<Gain> gains = getGainOf(currentMonth.getMonthOfYear(), currentMonth.getYear());
			List<Spent> spents = getSpentOf(currentMonth.getMonthOfYear(), currentMonth.getYear());

			lessProfitMonthBalanceReport.add( new MonthBalance(currentMonth.getMonthOfYear(), currentMonth.getYear(), gains, spents) );
			
			currentMonth = currentMonth.plusMonths(1);
		}
		
		Collections.sort( lessProfitMonthBalanceReport );
	}
	
	public void generateTotalSpentBalanceByMonth() {
		DateTime currentMonth = AppConfig.getStartDate();
		while( currentMonth.isBefore( new DateTime() ) ) {
			List<Spent> spents = getSpentOf(currentMonth.getMonthOfYear(), currentMonth.getYear());
			monthSpentReport.add( new MonthSpent(currentMonth.getMonthOfYear(), currentMonth.getYear(), spents) );
			
			currentMonth = currentMonth.plusMonths( 1 );
		}
		
		Collections.sort(monthSpentReport, Collections.reverseOrder());
	}
	
	private List<Gain> getGainOf(Integer month, Integer year) {
		List<Gain> gains = new ArrayList<Gain>(); 
		for( Gain gain : this.gains ) {
			if( gain.isIn( year, Month.findById(month) ) ) {
				gains.add( gain );
			}
		}
		return gains;
	}
	
	private List<Spent> getSpentOf(Integer month, Integer year) {
		List<Spent> spents = new ArrayList<Spent>(); 
		for( Spent spent: this.spents ) {
			if( spent.isIn(year, Month.findById(month) ) ) {
				spents.add( spent );
			}
		}
		return spents;
	}

	public List<MonthGain> getMonthGainReport() {
		return monthGainReport;
	}

	public List<MonthSpent> getMonthSpentReport() {
		return monthSpentReport;
	}

	public List<MonthBalance> getMoreProfitMonthBalanceReport() {
		return moreProfitMonthBalanceReport;
	}
	
	public List<MonthBalance> getLessProfitMonthBalanceReport() {
		return lessProfitMonthBalanceReport;
	}

}
